package net.wantongtech.xa.uploadbasicinfo.service;

import cn.com.taiji.sdk.model.comm.protocol.sdts.backlist.CardBlackListDownloadModel;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.wantongtech.xa.uploadbasicinfo.dao.DownloadReceiveFileDao;
import net.wantongtech.xa.uploadbasicinfo.util.BlackListFileUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.Validate;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

/**
 * 填充历史黑名单
 *
 * @author MaShibo
 * 2021/4/2 0002
 */
@Slf4j
public class FillCardBlackHisRecordService {


    private final DateTimeFormatter versionDateFormatter = DateTimeFormat.forPattern("yyyyMMddHHmm");

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Resource
    private DownloadReceiveFileDao downloadReceiveFileDao;

    public void fill(String savePath, String startVersion, String endVersion) {

        LocalDateTime startDateTime = LocalDateTime.parse(startVersion, versionDateFormatter);
        LocalDateTime endDateTime = LocalDateTime.parse(endVersion, versionDateFormatter);

        List<String> allVersionList = Lists.newArrayList();
        LocalDateTime tmpDateTime = startDateTime;
        while (tmpDateTime.compareTo(endDateTime) <= 0) {
            String version = tmpDateTime.toString(versionDateFormatter);
            allVersionList.add(version);
            tmpDateTime = tmpDateTime.plusMinutes(5);
        }

        for (String version : allVersionList) {

            try {
                Path targetPath = Paths.get(savePath, String.format("%s.zip", version));
                File targetFile = BlackListFileUtil.downloadCardBlackFileByVersion(version, targetPath.toString());

                String storePath = targetFile.getAbsolutePath();
                String firstExtractPath = storePath.substring(0, storePath.lastIndexOf('.'));

                extractZipFile(targetFile, firstExtractPath);

                File firstDir = new File(firstExtractPath);
                File[] firstDirFiles = firstDir.listFiles(((dir, name) -> name.contains("61")));

                if (ArrayUtils.isEmpty(firstDirFiles)) {
                    continue;
                }

                File firstDirFile = firstDirFiles[0];

                File[] jsonFiles = extractBlackListJsonFiles(firstDirFile);

                for (File jsonFile : jsonFiles) {
                    String json = jsonFile2String(jsonFile);
                    List<CardBlackListDownloadModel> modelList =
                            objectMapper.readValue(json, new TypeReference<List<CardBlackListDownloadModel>>() {
                            });
                    downloadReceiveFileDao.saveCardBlackHisRecordToSpecTable(modelList, version, "bl_his_cardrecord_2021");
                }

                log.info("版本{}处理完成", version);


            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }

        }
    }

    private void extractZipFile(File targetFile, String destDir) throws ZipException {
        Validate.notNull(targetFile, "zip文件路径不能为空");
        Validate.notBlank(destDir, "解压路径不能为空");
        ZipFile zipFile = new ZipFile(targetFile);
        zipFile.extractAll(destDir);
    }

    private File[] extractBlackListJsonFiles(File firstDirFile) throws ZipException {
        String firstDirFilePath = firstDirFile.getAbsolutePath();
        //第二层解压路径，包含：202102190935_61_1.json
        String secondExtractPath = firstDirFilePath.substring(0, firstDirFilePath.lastIndexOf('.'));

        extractZipFile(firstDirFile, secondExtractPath);

        return new File(secondExtractPath).listFiles((dir, name) -> name.endsWith(".json"));
    }

    private String jsonFile2String(File jsonFile) throws IOException {
        try (FileInputStream fis = new FileInputStream(jsonFile)) {
            return IOUtils.toString(fis, StandardCharsets.UTF_8.displayName());
        }
    }
}
